home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
cpp_libs
/
varia
/
silo.lha
/
silo
/
Sim.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-08
|
3KB
|
165 lines
/* $Author: ecsv38 $ $Date: 90/08/21 14:45:59 $ $Revision: 1.1 $ */
/* (c) S. Manoharan sam@lfcs.edinburgh.ac.uk */
#include "Counter.h"
#include "Sim.h"
#include "SimEventList.h"
static Counter timer;
static SimEventList eventlist;
Event *cause()
{
if ( debug_level(1) ) {
cout << "\n---Begin{eventlist}\n";
::eventlist.print();
cout << "\n---End{eventlist}\n";
}
Event *ev = ::eventlist.get();
if ( ev == 0 ) return 0;
if ( ev->eventTime() > ::timer() )
::timer.set(ev->eventTime());
return ev;
}
short cancel(const int eid)
{
Event *ev = ::eventlist.remove(eid);
if ( ev == 0 ) return 0;
else {
delete ev;
return 1;
}
}
double simtime()
{
return timer();
}
Entity::Entity(char *const s)
{
static int eid = 0;
entity_name = s, entity_id = eid++;
}
void
Entity::schedule(const double delay, Event *const ev)
{
if ( delay < 0 ) {
cout << form("%s: invalid delay %g\n", entity_name, delay);
exit(-1);
}
ev->scheduled_by(this);
ev->eventTime(::timer() + delay);
::eventlist.append(ev);
}
short
Resource::reserve(Entity *bywho, const int event_type)
{
resource_used = 1;
if ( bywho == 0 )
cout << form("** Error: reserve by null entity\n");
bywho->currentEvent(event_type);
bywho->afterTime = 0;
if ( available > 0 ) {
--available;
servedQ.append(bywho);
return 1;
}
else {
blockedQ.append(bywho);
return 0;
}
}
short
Resource::preempt(Entity *bywho, const int event_type)
{
resource_used = 1;
if ( bywho == 0 )
cout << form("** Error: preempt by null entity\n");
bywho->currentEvent(event_type);
bywho->afterTime = 0;
if ( available > 0 ) {
--available;
servedQ.append(bywho);
return 1;
}
else {
Entity *minPrioEnt = servedQ.remove(servedQ.min_entity_id());
if ( minPrioEnt->priority() >= bywho->priority() ) { // no preempt
blockedQ.append(bywho);
servedQ.append(minPrioEnt);
return 0;
}
else { // preempt
servedQ.append(bywho);
Event *stopped = ::eventlist.remove(minPrioEnt);
if ( stopped == 0 ) {
cout << form("** Error: no events for preempted entity\n");
return 0;
}
minPrioEnt->afterTime = stopped->eventTime() - simtime();
minPrioEnt->currentEvent(stopped->type());
blockedQ.insert(minPrioEnt);
delete stopped;
return 1;
}
}
}
void
Resource::release(Entity *const bywho)
{
Entity *entity;
if ( bywho == 0 )
cout << form("** Error: release by null entity\n");
if ( debug_level(1) ) {
cout << form("Releasing resource %s\n", resource_name);
cout << "\n---Begin{blockedQ}\n";
blockedQ.print();
cout << "\n---End{blockedQ}\n";
}
if ( servedQ.remove(bywho->id()) == 0 )
cout << form("** Error: release without reserve\n");
if ( ( entity = blockedQ.get() ) != 0 ) {
Event *event = new Event(entity->currentEvent());
entity->schedule(entity->afterTime, event);
if ( entity->afterTime == 0 ) ++available;
}
else ++available;
}
void
Resource::set(const int sz)
{
if ( resource_used ) {
cout << form("%s: resource already used. cannot set size\n",
resource_name);
exit(-1);
}
available = sz;
}